home *** CD-ROM | disk | FTP | other *** search
-
- /*
- * Copyright (c) 1985 Regents of the University of California.
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms are permitted
- * provided that this notice is preserved and that due credit is given
- * to the University of California at Berkeley. The name of the University
- * may not be used to endorse or promote products derived from this
- * software without specific prior written permission. This software
- * is provided ``as is'' without express or implied warranty.
- */
-
- /*
- ** Modified for and distributed with 'dig' version 2.0 from
- ** University of Southern California Information Sciences Institute
- ** (USC-ISI). 9/1/90
- */
-
-
- #if defined(LIBC_SCCS) && !defined(lint)
- static char sccsid[] = "@(#)res_debug.c 5.22 (Berkeley) 3/7/88";
- #endif /* LIBC_SCCS and not lint */
-
- #if defined(lint) && !defined(DEBUG)
- #define DEBUG
- #endif
-
- #ifndef RES_DEBUG
- #define RES_DEBUG2 0x80000000
- #endif
-
- #include "hfiles.h"
-
- #include <sys/types.h>
- #include <netinet/in.h>
- #include <stdio.h>
- #include NAMESERH
- #ifndef T_TXT
- #define T_TXT 16
- #endif T_TXT
- #include RESOLVH
- #include "pflag.h"
- #include NETDBH
-
-
- extern char *p_cdname(), *p_rr(), *p_type(), *p_class();
- extern char *inet_ntoa();
-
- char *_res_opcodes[] = {
- "QUERY",
- "IQUERY",
- "CQUERYM",
- "CQUERYU",
- "4",
- "5",
- "6",
- "7",
- "8",
- "UPDATEA",
- "UPDATED",
-
- "UPDATEDA",
- "UPDATEM",
- "UPDATEMA",
- "ZONEINIT",
- "ZONEREF",
- };
-
- char *_res_resultcodes[] = {
- "NOERROR",
- "FORMERR",
- "SERVFAIL",
- "NXDOMAIN",
- "NOTIMP",
- "REFUSED",
- "6",
- "7",
- "8",
- "9",
- "10",
- "11",
- "12",
- "13",
- "14",
- "NOCHANGE",
- };
-
-
- static char wksbuf[16];
-
- char * dewks(wks)
- int wks;
- {
- switch (wks) {
- case 5: return("rje");
- case 7: return("echo");
- case 9: return("discard");
- case 11: return("systat");
- case 13: return("daytime");
- case 15: return("netstat");
- case 17: return("qotd");
- case 19: return("chargen");
- case 20: return("ftp-data");
- case 21: return("ftp");
- case 23: return("telnet");
- case 25: return("smtp");
- case 37: return("time");
- case 39: return("rlp");
- case 42: return("name");
- case 43: return("whois");
- case 53: return("domain");
- case 57: return("apts");
- case 59: return("apfs");
- case 67: return("bootps");
- case 68: return("bootpc");
- case 69: return("tftp");
- case 77: return("rje");
- case 79: return("finger");
- case 87: return("link");
- case 95: return("supdup");
- case 100: return("newacct");
- case 101: return("hostnames");
- case 102: return("iso-tsap");
- case 103: return("x400");
- case 104: return("x400-snd");
- case 105: return("csnet-ns");
- case 109: return("pop-2");
- case 111: return("sunrpc");
- case 113: return("auth");
- case 115: return("sftp");
- case 117: return("uucp-path");
- case 119: return("nntp");
- case 121: return("erpc");
- case 123: return("ntp");
- case 133: return("statsrv");
- case 136: return("profile");
- case 144: return("NeWS");
- case 161: return("snmp");
- case 162: return("snmp-trap");
- case 170: return("print-srv");
- default: (void) sprintf(wksbuf, "%d", wks);
- return(wksbuf);
- }
- }
-
- char * deproto(protonum)
- int protonum;
- {
-
- switch (protonum) {
-
- case 1: return("icmp");
- case 2: return("igmp");
- case 3: return("ggp");
- case 5: return("st");
- case 6: return("tcp");
- case 7: return("ucl");
- case 8: return("egp");
- case 9: return("igp");
- case 11: return("nvp-II");
- case 12: return("pup");
- case 16: return("chaos");
- case 17: return("udp");
- default: (void) sprintf(wksbuf, "%d", protonum);
- return(wksbuf);
- }
- }
-
- p_query(msg)
- char *msg;
- {
- #ifdef DEBUG
- fp_query(msg,stdout);
- #endif
- }
-
- char *
- do_rrset(msg,cp,cnt,pflag,file,hs)
- int cnt, pflag;
- char *cp,*msg, *hs;
- FILE *file;
- {
- int n;
- char *pp;
- char *t1, *t2, *list[100],**tt;
- int sflag;
- /*
- * Print answer records
- */
- sflag = (pfcode & pflag);
- if (n = ntohs(cnt)) {
- *list=NULL;
- if ((sflag) && (pfcode & PRF_HEAD1))
- fprintf(file,hs);
- while (--n >= 0) {
- pp = (char *) malloc(512);
- *pp=0;
- cp = p_rr(cp, msg, pp);
- if ((cp-msg) > PACKETSZ)
- return (NULL);
-
- if (sflag) {
- if (pfcode & PRF_SORT) {
- for (tt=list, t1=pp, t2=NULL;
- ((*tt != NULL) && (strcmp(*tt,t1) < 1));) {
- tt++;
- }
- while (t1 != NULL) {
- t2 = *tt;
- *tt++ = t1;
- t1 = t2;
- }
- *tt = t1;
- }
- else {
- fprintf(file,"%s",pp);
- free(pp);
- }
- } else
- free(pp);
- }
-
- if (pfcode & pflag) {
- if (pfcode & PRF_SORT) {
- tt=list;
- while (*tt != NULL) {
- fprintf(file,"%s",*tt);
- free(*tt++);
- }
- }
- if (pfcode & PRF_HEADX)
- fprintf(file,"\n");
- }
- }
- return(cp);
- }
-
-
- /*
- * Print the contents of a query.
- * This is intended to be primarily a debugging routine.
- */
- fp_query(msg,file)
- char *msg;
- FILE *file;
- {
- register char *cp;
- register HEADER *hp;
- register int n;
- char zfile[256], tfile[100];
-
- /*
- * Print header fields.
- */
- hp = (HEADER *)msg;
- cp = msg + sizeof(HEADER);
- if ((pfcode & PRF_HEADX) || hp->rcode) {
- fprintf(file,";; ->>HEADER<<- ");
- fprintf(file,"opcode: %s ", _res_opcodes[hp->opcode]);
- fprintf(file,", status: %s", _res_resultcodes[hp->rcode]);
- /* if (pfcode & PRF_TTLID) XXXX */
- fprintf(file,", id: %d", ntohs(hp->id));
- putc('\n',file);
- }
- if (pfcode & PRF_HEAD2) {
- fprintf(file,";; flags:");
- if (hp->qr)
- fprintf(file," qr");
- if (hp->aa)
- fprintf(file," aa");
- if (hp->tc)
- fprintf(file," tc");
- if (hp->rd)
- fprintf(file," rd");
- if (hp->ra)
- fprintf(file," ra");
- if (hp->pr)
- fprintf(file," pr");
- if (_res.options & RES_DEBUG2)
- fprintf(file," res_opts: %x", _res.options);
- putc(' ',file);
- }
- if (pfcode & PRF_HEAD1) {
- fprintf(file,"; Ques: %d, ", ntohs(hp->qdcount));
- fprintf(file,"Ans: %d, ", ntohs(hp->ancount));
- fprintf(file,"Auth: %d, ", ntohs(hp->nscount));
- fprintf(file,"Addit: %d", ntohs(hp->arcount));
- }
- if (pfcode & (PRF_HEADX | PRF_HEAD2 | PRF_HEAD1))
- putc('\n',file);
- /*
- * Print question records.
- */
- if (n = ntohs(hp->qdcount)) {
- if (pfcode & PRF_QUES)
- fprintf(file,";; QUESTIONS: \n");
- while (--n >= 0) {
- sprintf(zfile,";;\t");
- cp = p_cdname(cp, msg, zfile);
- if (cp == NULL)
- return;
- sprintf(tfile,", type = %s", p_type(_getshort(cp)));
- strcat(zfile,tfile);
- cp += sizeof(u_short);
- sprintf(tfile,", class = %s\n", p_class(_getshort(cp)));
- strcat(zfile,tfile);
- cp += sizeof(u_short);
- if (pfcode & PRF_QUES)
- fprintf(file,"%s",zfile);
- }
- if (pfcode & PRF_QUES)
- fprintf(file,"\n");
- }
-
- /*
- * Print authoritative answer records
- */
-
- if ((cp = do_rrset(msg,cp,hp->ancount,PRF_ANS,file,";; ANSWERS:\n")) == NULL)
- return;
-
- /*
- * print name server records
- */
-
- if ((cp = do_rrset(msg,cp,hp->nscount,PRF_AUTH,file,
- ";; AUTHORITY RECORDS:\n")) == NULL)
- return;
-
- /*
- * print additional records
- */
-
- if ((cp = do_rrset(msg,cp,hp->arcount,PRF_ADD,file,
- ";; ADDITIONAL RECORDS:\n")) == NULL)
- return;
-
- } /* end function */
-
-
-
- char *
- p_cdname(cp, msg, p)
- char *cp, *msg;
- char *p;
- {
- #ifdef DEBUG
- char name[MAXDNAME];
- int n;
-
- if ((n = dn_expand(msg, msg + 512, cp, name, sizeof(name))) < 0)
- return (NULL);
- if (name[0] == '\0') {
- name[0] = '.';
- name[1] = '\0';
- }
- strcat(p,name);
- return (cp + n);
- #endif
- }
-
-
-
- /********************************************************
- * Print resource record fields in human readable form.
- ********************************************************/
- char *
- p_rr(cp, msg,p)
- char *cp, *msg, *p;
- {
- #ifdef DEBUG
- int type, class, dlen, n, c, xx,lcnt;
- struct in_addr inaddr;
- char *cp1;
- unsigned long tmpttl;
- struct servent *service;
- struct protoent *protocol;
- char file[130];
-
- if ((cp = p_cdname(cp, msg, p)) == NULL)
- return (NULL); /* compression error */
-
- if (*(p+strlen(p)-1) != '.')
- strcat(p,".");
-
- type = _getshort(cp);
- cp += sizeof(u_short);
- class = _getshort(cp);
- cp += sizeof(u_short);
- tmpttl = _getlong(cp);
- cp += sizeof(u_long);
-
- if (pfcode & PRF_TTLID) {
- sprintf(file,"\t%d",tmpttl);
- strcat(p,file);
- }
-
- if (pfcode & PRF_CLASS)
- sprintf(file,"\t%s\t%s",p_class(class), p_type(type));
- else
- sprintf(file,"\t%s", p_type(type));
- strcat(p, file);
-
- dlen = _getshort(cp);
- cp += sizeof(u_short);
- cp1 = cp;
- /*
- * Print type specific data, if appropriate
- */
- switch (type) {
- case T_A:
- switch (class) {
- case C_IN:
- bcopy(cp, (char *)&inaddr, sizeof(inaddr));
- if (dlen == 4) {
- sprintf(file,"\t%s",inet_ntoa(inaddr));
- strcat(p,file);
- cp += dlen;
- } else if (dlen == 7) {
- strcat(p,inet_ntoa(inaddr));
- sprintf(file,";; proto: %d", cp[4]);
- strcat(p,file);
- sprintf(file,", port: %d",
- (cp[5] << 8) + cp[6]);
- strcat(p,file);
- cp += dlen;
- }
- break;
- default:
- cp += dlen;
- }
- break;
- case T_CNAME:
- case T_MB:
- #ifdef OLDRR
- case T_MD:
- case T_MF:
- #endif /* OLDRR */
- case T_MG:
- case T_MR:
- case T_NS:
- case T_PTR:
- strcat(p,"\t");
- cp = p_cdname(cp, msg, p);
- strcat(p,".");
- break;
-
- case T_HINFO:
- if (n = *cp++) {
- sprintf(file,"\t%.*s ", n, cp);
- strcat(p,file);
- cp += n;
- }
- if (n = *cp++) {
- sprintf(file,"%.*s", n, cp);
- strcat(p,file);
- cp += n;
- }
- break;
-
- case T_UINFO:
- sprintf(file,"\t%s", cp);
- strcat(p,file);
- cp += dlen;
- break;
-
- case T_TXT:
- xx=0;
- while (xx++<dlen) {
- if (n = *cp++) {
- sprintf(file,"\t%.*s",n,cp);
- strcat(p,file);
- cp += (n-1);
- xx += n;
- if (*cp++ != '\n')
- strcat(p,"\n");
- }
- }
- strcat(p,"\n");
- break;
-
- case T_SOA:
- strcat(p,"\t");
- cp = p_cdname(cp, msg, p);
- strcat(p,". ");
- cp = p_cdname(cp, msg, p);
- sprintf(file,". (\n\t\t\t%ld\t;serial\n", _getlong(cp));
- strcat(p,file);
- cp += sizeof(u_long);
- sprintf(file,"\t\t\t%ld\t;refresh\n", _getlong(cp));
- strcat(p,file);
- cp += sizeof(u_long);
- sprintf(file,"\t\t\t%ld\t;retry\n", _getlong(cp));
- strcat(p,file);
- cp += sizeof(u_long);
- sprintf(file,"\t\t\t%ld\t;expire\n", _getlong(cp));
- strcat(p,file);
- cp += sizeof(u_long);
- sprintf(file,"\t\t\t%ld )\t;minim\n", _getlong(cp));
- strcat(p,file);
- cp += sizeof(u_long);
- break;
-
- case T_MX:
- sprintf(file,"\t%ld ",_getshort(cp));
- strcat(p,file);
- cp += sizeof(u_short);
- cp = p_cdname(cp, msg, p);
- strcat(p,".");
- break;
-
- case T_MINFO:
- strcat(p,"\t");
- cp = p_cdname(cp, msg, p);
- strcat(p,". ");
- cp = p_cdname(cp, msg, p);
- strcat(p,". ");
- break;
-
-
- case T_UID:
- case T_GID:
- if (dlen == 4) {
- sprintf(file,"\t%ld", _getlong(cp));
- strcat(p,file);
- cp += sizeof(int);
- }
- break;
-
- case T_WKS:
- if (dlen < sizeof(u_long) + 1)
- break;
- bcopy(cp, (char *)&inaddr, sizeof(inaddr));
- cp += sizeof(u_long);
-
- /* Although more portable, quite slow ...
-
- if ((protocol = getprotobynumber((int) *cp)) != NULL) {
- sprintf(file,"\t %s %s (\n", inet_ntoa(inaddr),
- protocol->p_name);
- } else {
- sprintf(file,"\t%s %d (\n", inet_ntoa(inaddr), *cp);
- }
- */
- sprintf(file, "\t %s %s (\n", inet_ntoa(inaddr),
- deproto((int) *cp));
-
- cp++;
- strcat(p,file);
- n = 0;
- strcat(p,"\t\t\t");
- lcnt = 5;
- while (cp < cp1 + dlen) {
- c = *cp++;
- do {
- if (c & 0200) {
-
- /* Although more portable, quite slow ... even using set/endservent()
-
- if ((service = getservbyport(n,NULL)) != NULL) {
- sprintf(file," %s", service->s_name);
- } else {
- sprintf(file, " %d", n);
- }
- */
- sprintf(file," %s", dewks(n));
- strcat(p,file);
- if (--lcnt == 0) {
- lcnt=5;
- strcat(p,"\n\t\t\t");
- }
- }
- c <<= 1;
- } while (++n & 07);
- }
- strcat(p," )");
- break;
-
- #ifdef ALLOW_T_UNSPEC
- case T_UNSPEC:
- {
- int NumBytes = 8;
- char *DataPtr;
- int i;
-
- if (dlen < NumBytes) NumBytes = dlen;
- sprintf(file, "\tFirst %d bytes of hex data:",
- NumBytes);
- strcat(p,file);
- for (i = 0, DataPtr = cp; i < NumBytes; i++, DataPtr++) {
- sprintf(file, " %x", *DataPtr);
- strcat(p,file);
- }
- strcat(p,"\n");
- cp += dlen;
- }
- break;
- #endif /* ALLOW_T_UNSPEC */
-
- default:
- strcat(p,"\t???\n");
- cp += dlen;
- }
- /*
- if (pfcode & PRF_TTLID) {
- sprintf(file,"\t; %d",tmpttl);
- strcat(p,file);
- }
- */
- strcat(p,"\n");
-
- if (cp != cp1 + dlen)
- fprintf(stdout,";; packet size error (%#x != %#x)\n", cp, cp1+dlen);
- return (cp);
- #endif
- }
-
- static char nbuf[20];
-
- /*
- * Return a string for the type
- */
- char *
- p_type(type)
- int type;
- {
- switch (type) {
- case T_A:
- return("A");
- case T_NS: /* authoritative server */
- return("NS");
- #ifdef OLDRR
- case T_MD: /* mail destination */
- return("MD");
- case T_MF: /* mail forwarder */
- return("MF");
- #endif /* OLDRR */
- case T_CNAME: /* connonical name */
- return("CNAME");
- case T_SOA: /* start of authority zone */
- return("SOA");
- case T_MB: /* mailbox domain name */
- return("MB");
- case T_MG: /* mail group member */
- return("MG");
- case T_MX: /* mail routing info */
- return("MX");
- case T_MR: /* mail rename name */
- return("MR");
- case T_NULL: /* null resource record */
- return("NULL");
- case T_WKS: /* well known service */
- return("WKS");
- case T_PTR: /* domain name pointer */
- return("PTR");
- case T_HINFO: /* host information */
- return("HINFO");
- case T_MINFO: /* mailbox information */
- return("MINFO");
- case T_AXFR: /* zone transfer */
- return("AXFR");
- case T_MAILB: /* mail box */
- return("MAILB");
- case T_MAILA: /* mail address */
- return("MAILA");
- case T_ANY: /* matches any type */
- return("ANY");
- case T_TXT:
- return("TXT");
- case T_UINFO:
- return("UINFO");
- case T_UID:
- return("UID");
- case T_GID:
- return("GID");
- #ifdef ALLOW_T_UNSPEC
- case T_UNSPEC:
- return("UNSPEC");
- #endif /* ALLOW_T_UNSPEC */
- default:
- (void)sprintf(nbuf, "%d", type);
- return(nbuf);
- }
- }
-
- /*
- * Return a mnemonic for class
- */
- char *
- p_class(class)
- int class;
- {
-
- switch (class) {
- case C_IN: /* internet class */
- return("IN");
- case C_ANY: /* matches any class */
- return("ANY");
- default:
- (void)sprintf(nbuf, "%d", class);
- return(nbuf);
- }
- }
-